import {
  Component,
  OnInit,
  forwardRef,
  ViewChild,
  Input,
  ChangeDetectorRef,
  HostBinding,
  Output,
  EventEmitter,
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

import {
  OverlayEntry,
  Placement,
  POSITION_MAP,
  DEFAULT_PICKER_POSITIONS,
  DropdownAnimation,
  Direction,
} from '../shared/shared';
import { TimepickerInnerComponent } from './timepicker-inner.component';

@Component({
  selector: 'fui-timepicker',
  templateUrl: './timepicker.component.html',
  animations: [
    DropdownAnimation,
  ],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => TimepickerComponent),
      multi: true,
    },
  ],
})
export class TimepickerComponent extends OverlayEntry implements OnInit, ControlValueAccessor {
  @HostBinding('class.fui-timepicker') hostClass = true;
  @ViewChild('trigger', { static: false }) trigger;
  @ViewChild(TimepickerInnerComponent, { static: false }) timepicker: TimepickerInnerComponent;

  value: Date = null;
  onChange: any = Function.prototype;
  onTouched: any = Function.prototype;

  /** Time format. */
  @Input() format = 'HH:mm:ss';

  /** Allow selecting hour. */
  @Input() allowHour = true;

  /** Allow selecting minute. */
  @Input() allowMinute = true;

  /** Allow selecting second. */
  @Input() allowSecond = true;

  /** Timepicker popup placement. */
  @Input() placement: Direction = 'top';

  /** Emit selected time. */
  @Output() selectedChange = new EventEmitter<Date>();

  constructor(
    private cdr: ChangeDetectorRef,
  ) {
    super();
  }

  ngOnInit() {
    this.setPosition(this.placement);
    this.visible.subscribe((visible: boolean) => {
      if (visible) {
        setTimeout(() => {
          this.timepicker.initPosition();
        }, 0);
      }
    });
  }

  setPosition(placement: Placement) {
    placement = placement || 'bottomLeft';
    this.positions = [POSITION_MAP[placement], ...DEFAULT_PICKER_POSITIONS];
    this.direction = this.toDirection(placement);
  }

  onTimeChange() {
    this.onChange(this.value);
    this.selectedChange.emit(this.value);
  }

  writeValue(value: any): void {
    this.value = value;
    this.cdr.detectChanges();
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }
}
